/****************************************************************************
*
*  ALi (Shanghai) Corporation, All Rights Reserved. 2003 Copyright (C)
*
*  File: win_upgrade_menu.c
*
*  Description: 
*              
*  History:
*      Date        	Author             	Version     	Comment
*      ====        	======        	=======   	=======
*
****************************************************************************/
#include <sys_config.h>
#include <types.h>
#ifdef _INVW_JUICE
#include <api/libfs2/stdio.h>
#endif
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#include <bus/otp/otp.h>

#include <api/libosd/osd_lib.h>
#include <api/libchunk/chunk.h>

#include "osdobjs_def.h"

#include "string.id"
#include "images.id"
#include "osd_config.h"
#include "osd_rsc.h"

#include "win_com_menu_define.h"
#include "win_com.h"
#include "menus_root.h"
#include "win_com_popup.h"

//add by bill 2012-02-13
#include <hal/hal_gpio.h>
#include "platform/board.h"

#ifdef _INVW_JUICE
#else
#include <api/libfs2/stdio.h>
#endif
#include <api/libfs2/statvfs.h>

//ChengYu@20131029, display firmware version
#include "aov_version.h"
/*******************************************************************************
* Objects declaration
*******************************************************************************/
extern CONTAINER win_info_con;

extern CONTAINER info_item_con;

extern TEXT_FIELD info_txt_name;

extern TEXT_FIELD info_txt1; //version or length

extern TEXT_FIELD info_txt2; //time or offset

extern TEXT_FIELD info_line; //time or offset

static const UINT32 chip_id_const = 505580010;
static VACTION info_con_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT info_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);
BOOL win_epg_is_show_logo(void);
static BOOL win_epg_set_show_state(void);

#ifndef SD_UI
#if Maker_GUI_ON
#ifndef SUPPORT_CAS_A
/* define in win_com_menu_define.h already */
#define	W_L     	Maker_GUI_SM_L
#define	W_T     	Maker_GUI_SM_T
#define	W_W     	Maker_GUI_SM_W
#define	W_H     	Maker_GUI_SM_H
#endif
#else
#ifndef SUPPORT_CAS_A
/* define in win_com_menu_define.h already */
#define	W_L     	248
#define	W_T     	98
#define	W_W     	692
#define	W_H     	488
#endif
#endif

#define CON_L		(W_L+20)
#define CON_T		(W_T + 4)
#define CON_W		(W_W - 60)
#define CON_H		40
#define CON_GAP		12

#define INFO_TXT_NAME_L 20
#define INFO_TXT_NAME_W 230//200
#define INFO_TXT1_L (INFO_TXT_NAME_L+INFO_TXT_NAME_W)

#if 1//ChengYu@20131029, display firmware version
#define INFO_TXT1_W 400
#define INFO_TXT2_L (INFO_TXT1_L+INFO_TXT1_W)
#define INFO_TXT2_W 0
#else
#define INFO_TXT1_W 230
#define INFO_TXT2_L (INFO_TXT1_L+INFO_TXT1_W)
#define INFO_TXT2_W 180
#endif

#define LINE_L_OF	0
#define LINE_T_OF  	(CON_H+4)
#define LINE_W		CON_W
#define LINE_H     	4

#else
#define	W_L     	105//384
#define	W_T     	57 //138
#define	W_W     	482
#define	W_H     	370

#ifdef CON_L
#undef CON_L
#endif

#ifdef CON_T
#undef CON_T
#endif

#ifdef CON_W
#undef CON_W
#endif

#ifdef CON_H
#undef CON_H
#endif

#ifdef CON_GAP
#undef CON_GAP
#endif

#define CON_L		(W_L+10)
#define CON_T		(W_T + 8)
#define CON_W		(W_W - 25)
#define CON_H		30
#define CON_GAP		8

#define INFO_TXT_NAME_L 10
#define INFO_TXT_NAME_W 180//200
#define INFO_TXT1_L (INFO_TXT_NAME_L+INFO_TXT_NAME_W)
#define INFO_TXT1_W 140
#define INFO_TXT2_L (INFO_TXT1_L+INFO_TXT1_W)
#define INFO_TXT2_W 100

#define LINE_L_OF	0
#define LINE_T_OF  	(CON_H+4)
#define LINE_W		CON_W
#define LINE_H     	4
#endif

#define LDEF_CON(root, varCon,nxtObj,l,t,w,h,conobj)		\
    DEF_CONTAINER(varCon,root,nxtObj,C_ATTR_ACTIVE,0, \
    1,1,1,1,1, l,t,w,h, CON_SH_IDX,CON_HL_IDX,CON_SL_IDX,CON_GRY_IDX,   \
     NULL,NULL,  \
    conobj, 0,0)
    
#define LDEF_TXT(root,varTxt,nxtObj,ID,l,t,w,h,resID,str)		\
    DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,ID,ID,ID,ID, l,t,w,h, TXTN_SH_IDX,TXTN_HL_IDX,TXTN_SL_IDX,TXTN_GRY_IDX,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,resID,str)

UINT16 info_name_str[30];
UINT16 info1_str[30];
UINT16 info2_str[30];
static BOOL epg_show_logo = TRUE;

#define FLAG_LOG_ENABLE    0x00000100  
#define FLAG_LOG_END       0x00000001
static char log_file_name[128];
static FILE *m_LogFile = NULL;
static OSAL_ID log_flag = OSAL_INVALID_ID;
static BOOL log_nim = FALSE;            


#define LDEF_LIST_ITEM(root,varCon,nxtObj,varTxtName,varTxt1,varTxt2,varLine,l,t,w,h)	\
	LDEF_CON(&root, varCon,nxtObj,l,t,w,h,&varTxtName)	\
	LDEF_TXT(&varCon,varTxtName,&varTxt1 ,1,l + INFO_TXT_NAME_L, t,INFO_TXT_NAME_W,h,0,info_name_str)	\
	LDEF_TXT(&varCon,varTxt1,&varTxt2 ,2,l + INFO_TXT1_L, t,INFO_TXT1_W,h,0,info1_str)	\
	LDEF_TXT(&varCon,varTxt2,NULL/*&varLine*/ ,3,l + INFO_TXT2_L, t,INFO_TXT2_W,h,0,info2_str)	\
	LDEF_LINE(&varCon,varLine,NULL,1,1,1,1,1,l + LINE_L_OF, t + LINE_T_OF,LINE_W,LINE_H,0,0)


LDEF_LIST_ITEM(win_info_con,info_item_con,NULL,info_txt_name,info_txt1,info_txt2,info_line,\
	CON_L, CON_T + (CON_H + CON_GAP)*0,CON_W,CON_H)

DEF_CONTAINER(win_info_con,NULL,NULL,C_ATTR_ACTIVE,0, \
    1,0,0,0,0, W_L,W_T,W_W,W_H, WIN_SH_IDX,WIN_HL_IDX,WIN_SL_IDX,WIN_GRY_IDX,   \
    info_con_keymap,info_con_callback,  \
    (POBJECT_HEAD)&info_item_con, 0,0)


//------------------------------------------------------------------------------
// Output string to the serial port, and log to file.
//------------------------------------------------------------------------------
static BOOL fs_is_available()
{
    struct statvfs usb_info;
	BOOL ret = TRUE;
    if (fs_statvfs("/mnt/uda1", &usb_info) <  0)
        ret = FALSE;
    else if(usb_info.f_bfree == 0)//usb device do not exist or mount failure
		ret = FALSE;
	return ret;
}

static BOOL log_open()
{
    FILE *fp;
    int i;
    date_time dt;

    if (log_flag != OSAL_INVALID_ID)
    {
        libc_printf("%s: The log had been turned on already - %s.\n", __FUNCTION__, log_file_name);
        return TRUE;
    }

    log_flag = osal_flag_create(FLAG_LOG_ENABLE);
    if (log_flag == OSAL_INVALID_ID)
    {
        libc_printf("%s: Fail to turn on.\n", __FUNCTION__);
        return FALSE;
    }

    do
    {
        log_file_name[0] = 0;   //clean up first.
        if( ! fs_is_available() )
            break;  //Output to the serial port only.

        i = 1;
        while(1)
        {
            if(i > 9999)
                break;
            sprintf(log_file_name, "/mnt/uda1/ali_log_%04d.txt",i++); //"/c/ali_log_%04d.txt"
            fp = fopen(log_file_name, "rb");
            if(NULL == fp)
                break;
            fclose(fp);
        }
        
        m_LogFile = fopen(log_file_name, "wb");
    }while(0);
    
    if ( ! m_LogFile && log_file_name[0]!=0 )
        libc_printf("%s: Can not create the log file - %s. Output to the serial port only.\n", __FUNCTION__, log_file_name);
    osal_flag_set(log_flag, FLAG_LOG_END);
    return TRUE;
}

static BOOL log_close()
{
    UINT32 flgptn;
    OSAL_ER result;
    result = osal_flag_wait(&flgptn, log_flag, FLAG_LOG_END, OSAL_TWF_ANDW|OSAL_TWF_CLR, 4*1000); 
    if(OSAL_E_OK != result)
        return FALSE;
    
    if(m_LogFile != NULL)
    {
        fclose(m_LogFile);
        fsync("/mnt/uda1");
        m_LogFile = NULL;
    }
    
    if (log_flag != OSAL_INVALID_ID)
    {
        osal_flag_delete(log_flag);
        log_flag = OSAL_INVALID_ID;
    }
    return TRUE;
}

void log_file_write(char *buffer)
{
    INT32 len;
    if(m_LogFile == NULL)
        return;

    len = strlen(buffer);

//        if( ! fs_is_available() )
//            return FALSE;

    if(len)
    {
        fwrite(buffer, 1, len, m_LogFile);
        fflush(m_LogFile);
    }
}

void log_string(char *buffer)
{
    UINT32 flgptn;
    OSAL_ER result;
    if (log_flag == OSAL_INVALID_ID)
    {
        libc_printf("%s: log_open() shall be called first.\n", __FUNCTION__);
        return FALSE;
    }
    result = osal_flag_wait(&flgptn, log_flag, FLAG_LOG_END, OSAL_TWF_ANDW|OSAL_TWF_CLR, 4*1000); 
    if(OSAL_E_OK != result)
        return;

    libc_printf("%s", buffer);
    log_file_write(buffer);

    osal_flag_set(log_flag,FLAG_LOG_END);
}
//------------------------------------------------------------------------------

    
/*******************************************************************************
*	Local functions & variables declare
*******************************************************************************/
static void set_info_con_rect(UINT16 l, UINT16 t, UINT16 w, UINT16 h)
{
	OSD_SetRect(&info_item_con.head.frame, l,t,w,h);
	OSD_SetRect(&info_txt_name.head.frame, l + INFO_TXT_NAME_L, t,INFO_TXT_NAME_W,h);
	OSD_SetRect(&info_txt1.head.frame, l + INFO_TXT1_L, t,INFO_TXT1_W,h);
	OSD_SetRect(&info_txt2.head.frame, l + INFO_TXT2_L, t,INFO_TXT2_W,h);
	OSD_SetRect(&info_line.head.frame, l + LINE_L_OF, t+LINE_T_OF,LINE_W,LINE_H);
}

static void display_sys_infomation(UINT8 flag)
{        
#if 1//ChengYu@20131029, display firmware version
	char str[50];
	SYSTEM_DATA *p_sys_data=sys_data_get();

	set_info_con_rect(CON_L, CON_T,CON_W,CON_H);
	ComUniStrCopyChar((UINT8*)len_display_str, OSD_GetUnicodeString(RS_INFO_SW));
	ComAscStr2Uni(" : ", (len_display_str+ComUniStrLen(len_display_str)));
	OSD_SetTextFieldContent((PTEXT_FIELD)&info_txt_name, STRING_UNICODE, len_display_str);
	
	sprintf(str, "%s-%s-%s", AOV_INFO_CUSTOMER_NAME, AOV_SYS_INFO_PRODUCT_NAME, AOV_SYS_INFO_VERSION);
	ComAscStr2Uni(str, len_display_str);
	OSD_SetTextFieldContent((PTEXT_FIELD)&info_txt1, STRING_UNICODE, len_display_str);
	OSD_DrawObject((POBJECT_HEAD )&info_item_con,C_UPDATE_ALL);

	set_info_con_rect(CON_L, CON_T + (CON_H + CON_GAP),CON_W,CON_H);
	ComUniStrCopyChar((UINT8*)len_display_str, OSD_GetUnicodeString(RS_INFO_BUILD_DATE));
	ComAscStr2Uni(" : ", (len_display_str+ComUniStrLen(len_display_str)));
	OSD_SetTextFieldContent(&info_txt_name, STRING_UNICODE, len_display_str);
	sprintf(str, "%s", AOV_SYS_BUILD_DATE);	
	ComAscStr2Uni(str, len_display_str);
	OSD_SetTextFieldContent((PTEXT_FIELD)&info_txt1, STRING_UNICODE, len_display_str);
	OSD_DrawObject((POBJECT_HEAD )&info_item_con,C_UPDATE_ALL);
#else
	CHUNK_HEADER blk_header;
	UINT8 i,j=0;
	UINT32 id,mask;
	char str[30];
	BYTE info_block_number;
	UINT32 len,chunkid,addr;
	UINT32 top = 0;
	UINT32 stb_sn_pre = 0;
	UINT32 stb_sn_lst = 0;
	UINT32 sc_chip_id = 0;
	//unsigned char hardware_date[] = {50,48,49,49,45,50,45,49,54};
	unsigned char * hardware_date = "2011-2-10";

#if (defined( SUPPORT_DVTCA) ||defined( SUPPORT_CAS9) || defined( SUPPORT_CAS7 )||defined(SUPPORT_VMX) || defined( SUPPORT_VMX_STD) || defined(FTA_ONLY))
	info_block_number = sto_chunk_count(0,0);
	for(i=0;i<info_block_number;i++)
	{
		id = mask = 0;
		sto_chunk_goto(&id,mask,i + 1);
		sto_get_chunk_header(id, &blk_header);
		if(id == MAINCODE_ID)
			break;
	}
#if defined(_VMX_CA_ENABLE_) || defined (_VMX_CA_STD_ENABLE_)
	for(i=0;i<5;i++)
#else
	for(i=0;i<3;i++)
#endif
	{
		set_info_con_rect(CON_L, CON_T + (CON_H + CON_GAP)*(i+top),CON_W,CON_H);
		MEMSET(str,0,sizeof(str));
		if(i==0)
			sprintf(str,"Hardware Version");
		else if(i==1)
			sprintf(str,"Software Version");
		else if(i==2)
			sprintf(str,"STB SN");
#if defined(_VMX_CA_ENABLE_) || defined (_VMX_CA_STD_ENABLE_)
		else if(i==3) // Manufacturer Id & Box Type Id for VMX
			sprintf(str,"Manufacture Id");
		else if(i==4)
			sprintf(str,"Box Type Id");
#endif
		else
			break;
		OSD_SetTextFieldContent(&info_txt_name,STRING_ANSI, (UINT32)str);
		if(flag==0)
		{
			if(i == 0)
			{
				//sprintf(str,"%x.%x.%x.%x",0,0,0,1);	    
				sprintf(str,"%d.%d.%d.%d",(SYS_HW_VERSION>>12)&0x0f,(SYS_HW_VERSION>>8)&0x0f,(SYS_HW_VERSION>>4)&0x0f,SYS_HW_VERSION&0x0f);
			}
			else if(i == 1)
			{
				sprintf(str,"%d.%d.%d.%d",blk_header.version[4]-'0',blk_header.version[5]-'0',blk_header.version[6]-'0',blk_header.version[7]-'0');
			}
#if defined(_VMX_CA_ENABLE_) || defined (_VMX_CA_STD_ENABLE_)
			else if(i==2)
#else
			else if( i ==2 || i==3 )   //STB SN
#endif
			{
#if (defined(_CAS9_CA_ENABLE_)|| defined(_VMX_CA_ENABLE_) || defined (_VMX_CA_STD_ENABLE_) )        
				chunkid = 0x20DF0100;	
				addr =  (UINT32)sto_chunk_goto(&chunkid,0xFFFFFFFF,1);//chunk addr
				UINT8 *sn_buf = MALLOC(128);
				sto_get_data((struct sto_device *)dev_get_by_id(HLD_DEV_TYPE_STO, 0), sn_buf, addr+CHUNK_HEADER_SIZE, 64);
				len = sn_buf[0];
				if(len >0 && len<0xFF)
				{
					if(i==2)
					{
						sn_buf[len+1]=0;
						sprintf(str,"%s",&sn_buf[1]);
					}
					else   //STB SN
					{
						sn_buf[32+13]=0;
						sprintf(str,"%s",&sn_buf[32+6]);					
					}
				}
				else
				{
#endif			
					otp_read(0, &sc_chip_id, 4);
					//sc_chip_id = 505580011;
					//libc_printf("sc_chip_id=%x %x %x %x\n",(sc_chip_id>>24)&0xff,(sc_chip_id>>16)&0xff,(sc_chip_id>>8)&0xff,sc_chip_id&0xff);
					if((((sc_chip_id>>24)&0xff) != 0x1e) && (((sc_chip_id>>16)&0xff) != 0x22))  //not commecial card
					{
						stb_sn_pre = 0;
						stb_sn_lst = 0;
						sprintf(str, "00000000000000000", stb_sn_pre,stb_sn_lst);
					}
					else
					{
						stb_sn_pre = 254110;
						stb_sn_lst = 40000001+(sc_chip_id-chip_id_const);
						sprintf(str, "000%6d%8d", stb_sn_pre,stb_sn_lst);
					}
#if (defined(_CAS9_CA_ENABLE_)|| defined(_VMX_CA_ENABLE_)  || (defined _VMX_CA_STD_ENABLE_))				
				}	
				FREE(sn_buf);
				sn_buf = NULL;
#endif
#ifndef SD_UI
				OSD_SetRect(&info_txt1.head.frame, CON_L + INFO_TXT1_L, CON_T + (CON_H + CON_GAP)*(i+top),INFO_TXT1_W+180,CON_H);
				OSD_SetRect(&info_txt2.head.frame, CON_L + INFO_TXT1_L+180, CON_T + (CON_H + CON_GAP)*(i+top),0,CON_H);
#else
				OSD_SetRect(&info_txt1.head.frame, CON_L + INFO_TXT1_L, CON_T + (CON_H + CON_GAP)*(i+top),INFO_TXT1_W+150,CON_H);
				OSD_SetRect(&info_txt2.head.frame, CON_L + INFO_TXT1_L+150, CON_T + (CON_H + CON_GAP)*(i+top),0,CON_H);
#endif			
			}
#if defined(_VMX_CA_ENABLE_) || defined (_VMX_CA_STD_ENABLE_)
			else if(i==3||i==4) // Manufacturer Id & Box Type Id for VMX, get from stb_info chunk
			{
				UINT16 manufacturer_code,manufacture_id;
				UINT32 individual_type,box_individual_type;
				chunkid = 0x20DF0100;	
				addr =  (UINT32)sto_chunk_goto(&chunkid,0xFFFFFFFF,1);//chunk addr
				sto_get_data((struct sto_device *)dev_get_by_id(HLD_DEV_TYPE_STO, 0), &box_individual_type, addr+CHUNK_HEADER_SIZE+64, 4);
				
				box_individual_type=Get32bit(&box_individual_type);
				manufacture_id=(UINT16)(box_individual_type>>20);
				box_individual_type=box_individual_type&0x000FFFFF;

				if(i==3)
				{
					sprintf(str,"%03x",manufacture_id);
				}
				else
				{
					sprintf(str,"%05x",box_individual_type);
				}
#ifndef SD_UI
				OSD_SetRect(&info_txt1.head.frame, CON_L + INFO_TXT1_L, CON_T + (CON_H + CON_GAP)*(i+top),INFO_TXT1_W+180,CON_H);
				OSD_SetRect(&info_txt2.head.frame, CON_L + INFO_TXT1_L+180, CON_T + (CON_H + CON_GAP)*(i+top),0,CON_H);
#else
				OSD_SetRect(&info_txt1.head.frame, CON_L + INFO_TXT1_L, CON_T + (CON_H + CON_GAP)*(i+top),INFO_TXT1_W+150,CON_H);
				OSD_SetRect(&info_txt2.head.frame, CON_L + INFO_TXT1_L+150, CON_T + (CON_H + CON_GAP)*(i+top),0,CON_H);
#endif
			}
#endif
			OSD_SetTextFieldContent(&info_txt1,STRING_ANSI, (UINT32)str);

			if(i==0)
			{
				OSD_SetTextFieldContent(&info_txt2,STRING_ANSI, (UINT32)hardware_date);
			}
			else if(i==1)
			{
				OSD_SetTextFieldContent(&info_txt2,STRING_ANSI, (UINT32)blk_header.time);
			}
        	}
		else
		{
			/*length*/
			sprintf(str,"0x%x",blk_header.len);
			OSD_SetTextFieldContent(&info_txt1,STRING_ANSI, (UINT32)str);

			/* Offset */
			sprintf(str,"0x%x",blk_header.offset);
			OSD_SetTextFieldContent(&info_txt2,STRING_ANSI, (UINT32)str);
		}
        	OSD_DrawObject((POBJECT_HEAD )&info_item_con,C_UPDATE_ALL);
    	}
#else
	info_block_number = sto_chunk_count(0,0);
	for(i=0;i<info_block_number;i++)
	{
		id = mask = 0;
		sto_chunk_goto(&id,mask,i + 1);
#ifndef UPG_MEMCFG_SUPPORT  //for 3503 not show memcfg info in menu
        if(ALI_S3503==sys_ic_get_chip_id() || ALI_S3821==sys_ic_get_chip_id())
        {
            if(i>=(info_block_number-1))
                break;
            if(i>=2)
        		sto_chunk_goto(&id,mask,i+1+1);
        }
#endif        

		sto_get_chunk_header(id, &blk_header);

		set_info_con_rect(CON_L, CON_T + (CON_H + CON_GAP)*(i+top),CON_W,CON_H);

		/* Name */
		OSD_SetTextFieldContent(&info_txt_name,STRING_ANSI, (UINT32)blk_header.name);


		if(flag == 0)
		{//show version & time

			/* Version */
			if(i==0)
				OSD_SetTextFieldContent(&info_txt1,STRING_ANSI, (UINT32)&blk_header.version[8]);
			else
				OSD_SetTextFieldContent(&info_txt1,STRING_ANSI, (UINT32)blk_header.version);

			/* Time */
			OSD_SetTextFieldContent(&info_txt2,STRING_ANSI, (UINT32)blk_header.time);
		}
		else
		{//show length & offset
		
			/*length*/
			sprintf(str,"0x%x",blk_header.len);
			OSD_SetTextFieldContent(&info_txt1,STRING_ANSI, (UINT32)str);
			
			/* Offset */
			sprintf(str,"0x%x",blk_header.offset);
			OSD_SetTextFieldContent(&info_txt2,STRING_ANSI, (UINT32)str);
		}

		OSD_DrawObject((POBJECT_HEAD )&info_item_con,C_UPDATE_ALL);
	}
#endif
#endif
}


static BOOL factorytest_check_magic_key(UINT32 code)
{
	static UINT8 magic_key[] = { V_KEY_1, V_KEY_1,V_KEY_1,V_KEY_1,V_KEY_1 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))	
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;
}

BOOL factorytest_check_magic_key_diag(UINT32 code)
{
	static UINT8 magic_key[] = { V_KEY_9, V_KEY_8,V_KEY_7,V_KEY_6,V_KEY_0 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))	
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;
}
//
static BOOL factorytest_check_hdmi_hdcp_key(UINT32 code)
{
    static UINT8 magic_key[] = { V_KEY_6, V_KEY_6,V_KEY_6,V_KEY_6,V_KEY_6 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;    
}
static BOOL factorytest_check_epg_show_logo_key(UINT32 code)
{
    static UINT8 magic_key[] = { V_KEY_8, V_KEY_8,V_KEY_8,V_KEY_8,V_KEY_8 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;    
}

static BOOL factorytest_check_opt_bonding_key(UINT32 code)
{
    static UINT8 magic_key[] = { V_KEY_5, V_KEY_5,V_KEY_5,V_KEY_5,V_KEY_5 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;    
}

static BOOL factorytest_check_adc_key(UINT32 code)
{
    static UINT8 magic_key[] = { V_KEY_7, V_KEY_7,V_KEY_7,V_KEY_7,V_KEY_7 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;    
}

static BOOL factorytest_check_log_nim_key(UINT32 code)
{
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))
	static UINT8 magic_log[] = { V_KEY_3, V_KEY_3,V_KEY_3,V_KEY_3,V_KEY_3 };
	static int log_cnt = 0;

	if (magic_log[log_cnt++] == code)
	{
		if (log_cnt == (int)(sizeof(magic_log)/sizeof(UINT8)))
		{
			log_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
	log_cnt = 0;
#endif	
    
	return FALSE;    
}

static BOOL factorytest_mute_gpio_key(UINT32 code)
{
    static UINT8 magic_key[] = { V_KEY_0, V_KEY_0,V_KEY_0,V_KEY_0,V_KEY_0 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))	
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;    
}
static BOOL factorytest_mute_uart_key(UINT32 code)
{
    static UINT8 magic_key[] = { V_KEY_9, V_KEY_9,V_KEY_9,V_KEY_9,V_KEY_9 };
	static int key_cnt = 0;
#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX))&&(!defined(SUPPORT_VMX_STD)))
	if (magic_key[key_cnt++] == code)
	{
		if (key_cnt == (int)(sizeof(magic_key)/sizeof(UINT8)))
		{
			key_cnt = 0;
			return TRUE;
		}
		else
			return FALSE;
	}
#endif	
	key_cnt = 0;
	return FALSE;    
}
/*******************************************************************************
*	Window's keymap, proc and  callback
*******************************************************************************/
static VACTION info_con_keymap(POBJECT_HEAD pObj, UINT32 vkey)
{
	VACTION act;
	
    switch(vkey)
    {
    case V_KEY_MENU:
    case V_KEY_EXIT:
        act = VACT_CLOSE;
		break;
	case V_KEY_0:	case V_KEY_1:	case V_KEY_2:	case V_KEY_3:
	case V_KEY_4:	case V_KEY_5:	case V_KEY_6:	case V_KEY_7:
	case V_KEY_8:	case V_KEY_9:
		act = vkey - V_KEY_0 + VACT_NUM_0;
		break;
    default:
        act = VACT_PASS;
    }

	return act;
}

static PRESULT info_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	CONTAINER* cont = (CONTAINER*)pObj;
	UINT8	id = OSD_GetObjID(pObj);
	POBJECT_HEAD submenu;

	switch(event)
	{
	case EVN_PRE_OPEN:
		wincom_open_title((POBJECT_HEAD)&win_info_con,RS_TOOLS_INFORMATION, 0);
		break;			
	case EVN_POST_OPEN:
		display_sys_infomation(0);
		break;		
	case EVN_PRE_CLOSE:
		/* Make OSD not flickering */
		*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;				
		break;
	case EVN_POST_CLOSE:
		break;
	case EVN_UNKNOWN_ACTION:
        param1 &= 0xff;
		if (factorytest_check_magic_key(param1))
		{
			submenu = (POBJECT_HEAD)&g_win_factory_test;
			if(OSD_ObjOpen(submenu, MENU_OPEN_TYPE_OTHER) != PROC_LEAVE)
				menu_stack_push(submenu);
            break;
		}
        
		if (factorytest_check_magic_key_diag(param1))
		{
			UINT16 channel = sys_data_get_cur_group_cur_mode_channel();
            UINT16 group_idx = sys_data_get_cur_group_index();
			sys_data_change_group(group_idx);

            api_stop_play(0); //to call si_monitor_off for fixing bug 13806 --Michael 2008/2/18
			api_play_channel(channel, TRUE, FALSE, FALSE);
            ap_clear_all_menus();
			extern CONTAINER win_diag;
			ap_send_msg(CTRL_MSG_SUBTYPE_CMD_ENTER_ROOT, (UINT32)&win_diag, TRUE);
            break;
		}
        
        if(factorytest_check_hdmi_hdcp_key(param1))
        {
            extern CONTAINER g_win_hdmi_factory_test;
            submenu = (POBJECT_HEAD)&g_win_hdmi_factory_test;
            if(OSD_ObjOpen(submenu,MENU_OPEN_TYPE_OTHER) != PROC_LEAVE)
            {
                menu_stack_push(submenu);
            }
            break;
        }

/*
#if (!defined _CAS9_CA_ENABLE_) && (!defined _VMX_CA_ENABLE_) && (!defined _VMX_CA_STD_ENABLE_)	
#if (!defined _S3811_)
        if(factorytest_check_opt_bonding_key(param1))
		{
			submenu = (POBJECT_HEAD)&g_win_otp_check;
			if(OSD_ObjOpen(submenu, MENU_OPEN_TYPE_OTHER) != PROC_LEAVE)
				menu_stack_push(submenu);
            break;
		}
#endif	
#endif	
*/

#if((!defined(SUPPORT_CAS9))&&(!defined(SUPPORT_VMX_STD))&&(!defined _VMX_CA_ENABLE_))
        if(factorytest_check_epg_show_logo_key(param1))
        {
            UINT8 back_saved;
            win_epg_set_show_state();
            win_compopup_init(WIN_POPUP_TYPE_SMSG);
            if(win_epg_is_show_logo())
            {
                win_compopup_set_msg("EPG Show Logo", NULL, 0);
            }
            else
            {
                win_compopup_set_msg("EPG Normal", NULL, 0);
            }
            win_compopup_open_ext(&back_saved);
            osal_task_sleep(2000);
            win_compopup_smsg_restoreback();
            break;
        }
#endif			

        if(check_magic_key_firmware_info(param1))
        {
            if (sys_ic_get_chip_id() >= ALI_S3602F)
                show_firmware_info();
            break;
        }
        
#ifndef DISABLE_PRINTF  //_CAS9_CA_ENABLE_	
        if(factorytest_check_adc_key(param1))
        {
	#ifdef  NIM_REG_ENABLE
            submenu = (POBJECT_HEAD)&g_win_adc;
            if(OSD_ObjOpen(submenu,MENU_OPEN_TYPE_OTHER) != PROC_LEAVE)
            {
                menu_stack_push(submenu);
            }
            break;
	#endif
        }
        if(factorytest_check_adc_key(param1))
        {
	#ifdef  DVBC_NIM_ADC_DEBUG
            submenu = (POBJECT_HEAD)&g_win_dvbc_adc;
            if(OSD_ObjOpen(submenu,MENU_OPEN_TYPE_OTHER) != PROC_LEAVE)
            {
                menu_stack_push(submenu);
            }
            break;
	#endif
        }

        if(factorytest_check_log_nim_key(param1))
        {
            UINT8 back_saved;
            char info[255];
            
        	struct nim_device * dev = (struct nim_device *)dev_get_by_id(HLD_DEV_TYPE_NIM, 0);
            if (!dev)
                break;

            win_compopup_init(WIN_POPUP_TYPE_SMSG);
			if (log_nim)
			{
                if ( m_LogFile )
                    sprintf(info, "log_close: %s",log_file_name);
                else
                    sprintf(info, "log_close: Serial port");
                win_compopup_set_msg(info, NULL, 0);
                
        	    nim_io_control(dev, NIM_DRIVER_DISABLE_DEBUG_LOG, (UINT32)NULL);
                if (log_close())
				    log_nim = FALSE;
			}
			else
			{
                log_open();
        	    nim_io_control(dev, NIM_DRIVER_ENABLE_DEBUG_LOG, (UINT32)log_string);
				log_nim = TRUE;
                
                if ( m_LogFile )
                    sprintf(info, "log_open: %s",log_file_name);
                else
                    sprintf(info, "log_open: Serial port");
                win_compopup_set_msg(info, NULL, 0);
			}

            win_compopup_open_ext(&back_saved);
            osal_task_sleep(4000);
            win_compopup_smsg_restoreback();

            ap_send_msg(CTRL_MSG_SUBTYPE_CMD_EXIT_ROOT, (UINT32)&win_info_con,FALSE);
            break;
        }
#endif

        //add by bill on 2012-02-13
        if(factorytest_mute_gpio_key(param1))
        {
    		//*(volatile UINT32*)(0xb8000088) &= ~(1<<8); 
    		*(volatile UINT32*)(0xb8000088) &= ~(3); 
    		*(volatile UINT32*)(0xb8000430) |=(1<<16);
    		HAL_GPIO_BIT_DIR_SET( 16, 1);	
    		*(volatile UINT32*)(0xb8000054)&=~(1<<15);
    		*(volatile UINT32*)(0xb8000430) |=(1<<15);
    		HAL_GPIO_BIT_DIR_SET( 15, 1);	
    		*(volatile UINT32*)(0xb8000054)|=(1<<15);
    			
    		//HAL_GPIO_BIT_DIR_SET( 16, 1);
    		//HAL_GPIO_BIT_SET( 16,0 );
    		pan_display(g_pan_dev, "0000", 4);
            break;
        }

        if(factorytest_mute_uart_key(param1))
        {
    		*(volatile UINT32*)(0xb8000430) &=~(3<<15);
    		//*(volatile UINT32*)(0xb8000088) |= 1<<8;
    		*(volatile UINT32*)(0xb8000088) |= 3;
    		//printf("UART MODE\n");
    		libc_printf("UART MODE\n");
    		pan_display(g_pan_dev, "9999", 4);
            break;
        }
        
		break;
	}
	return ret;
}

BOOL win_epg_is_show_logo(void)
{
    return epg_show_logo;
}
static BOOL win_epg_set_show_state(void)
{
    epg_show_logo = epg_show_logo?FALSE:TRUE;
}


